package com.sanyou.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sanyou.enums.MaintainType;
import com.sanyou.mapper.*;
import com.sanyou.pojo.*;
import com.sanyou.pojo.dto.ProductInfoDTO;
import com.sanyou.pojo.dto.SimpleProductDTO;
import com.sanyou.pojo.vo.MaintainDataVo;
import com.sanyou.pojo.vo.ProductCountVo;
import com.sanyou.pojo.vo.ProductMaintainVo;
import com.sanyou.pojo.vo.ProductNumVo;
import com.sanyou.pojo.vo.ProductVo;
import com.sanyou.service.DataInfoService;
import com.sanyou.service.FactoryService;
import com.sanyou.service.MaintainHistoryService;
import com.sanyou.service.OperLogService;
import com.sanyou.service.ProductService;
import com.sanyou.service.UserService;
import com.sanyou.utils.PagedResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.text.DecimalFormat;
import java.util.*;

/**
 * User: asus
 * Date: 2021-12-14
 * Time: 13:36
 * Version:V1.0
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private IndustryDataMapper industryDataMapper;

    @Autowired
    private CollectHistoryMapper collectHistoryMapper;

    @Autowired
    private SearchHistoryMapper searchHistoryMapper;

    @Autowired
    private OrderProductMapper orderProductMapper;

    @Autowired
    private VerticalityDataMapper verticalityDataMapper;

    @Autowired
    private FactoryMapper factoryMapper;

    @Autowired
    private MaintainHistoryService maintainHistoryService;

    @Autowired
    private UserService userService;

    @Autowired
    private FactoryService factoryService;

    @Autowired
    private OperLogService operLogService;

    @Autowired
    private DataInfoService dataInfoService;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ProductVo> listProductInfo(String productCode, Integer productState,Integer maintainType,
                                           Integer orderId,Integer projectId, String factoryId, String subFactoryId,String userid) {
        return productMapper.listProductInfo(productCode,productState,maintainType,orderId,projectId,factoryId,subFactoryId,userid);
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PageInfo<SimpleProductDTO> queryByProjectId(String projectId, Integer page, Integer pageSize){
        PageHelper.startPage(page,pageSize);
        List<SimpleProductDTO> dataList = productMapper.queryByProjectId(projectId);
        PageInfo<SimpleProductDTO> pageList = new PageInfo<>(dataList);
        return pageList;
    };


    @Override
    public PageInfo<ProductVo> listProductInfo(String productCode, Integer productState,Integer maintainType,
                                               Integer orderId,Integer projectId, String factoryId, String subFactoryId,String userid, Integer page, Integer pageSize) {
        if(page == null || pageSize == null){
            return null;
        }

        //分页设置
        PageHelper.startPage(page,pageSize);

        //查询阴极板信息列表
        List<ProductVo> dataList = this.listProductInfo(productCode,productState,maintainType,orderId,projectId,factoryId,subFactoryId,userid);


        //封装分页返回对象
        PageInfo<ProductVo> pageList = new PageInfo<>(dataList);
        return pageList;
    }

    @Override
    public PageInfo<ProductVo> listAllProductInfo(Integer page, Integer pageSize) {
        return this.listProductInfo(null,null,null,null,null,null,null,null,page,pageSize);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Product> listProductByCode(String productCode) {
        if (StringUtils.isEmpty(productCode)){
            return null;
        }

        return productMapper.listProductByCode(productCode);
    }

    @Override
    public PageInfo<Product> listProductByCode(String productCode, Integer page, Integer pageSize) {
        //分页设置
        PageHelper.startPage(page,pageSize);

        //查询阴极板信息列表
        List<Product> dataList = this.listProductByCode(productCode);


        //封装分页返回对象
        PageInfo<Product> pageList = new PageInfo<>(dataList);
        return pageList;
    }

    @Override
    public ProductVo getProductInfoByCode(String productCode) {
        if(StringUtils.isEmpty(productCode)){
            return null;
        }

//        List<ProductVo> list = this.listProductInfo(productCode,null,null,null,null,null,null,null);
//
//        if(list!=null && list.size() > 0){
//            return list.get(0);
//        }

        return productMapper.selectByCode(productCode);
    }

    @Override
    public boolean productIsCollected(String productCode, String userId) {
        Example example = new Example(CollectHistory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andEqualTo("collectCode",productCode);
        List<CollectHistory> collectHistoryList = collectHistoryMapper.selectByExample(example);
        if(collectHistoryList != null && collectHistoryList.size() > 0)
            return true;
        return false;
    }

//    @Transactional(propagation = Propagation.SUPPORTS)
//    @Override
//    public PagedResult query(ProductVo queryVo, Integer page, Integer pageSize) {
//
//        PageHelper.startPage(page,pageSize);
//        List<ProductMaintainVo> dataList = productMapper.query(queryVo);
//
//        for (ProductMaintainVo vo : dataList) {
//            if(vo.getProductState() == null || vo.getProductState() != MaintainType.Maintaining.getCode()){
//                vo.setMaintainType(null);
//                vo.setUpdateMaintainDate(null);
//            }
//            if(vo.getYjbLength() != null && vo.getYjbWidth() != null && vo.getYjbHeight() != null)
//                vo.setYjbSize(vo.getYjbLength() + "*" + vo.getYjbWidth() + "*" + vo.getYjbHeight());
//
//            if(vo.getProductPlane() != null){
//                DecimalFormat df = new DecimalFormat("#.00");
//                String format = df.format(vo.getProductPlane());
//                vo.setProductPlane(Double.valueOf(format));
//            }
//        }
//
//        PageInfo<ProductMaintainVo> pageList = new PageInfo<>(dataList);
//
//        PagedResult pagedResult = new PagedResult();
//        pagedResult.setPage(page);
//        pagedResult.setTotal(pageList.getPages());
//        pagedResult.setRows(dataList);
//        pagedResult.setRecords(pageList.getTotal());
//        return pagedResult;
//    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PageInfo<Product> queryAll(Integer page, Integer pageSize) {
        //分页设置
        PageHelper.startPage(page,pageSize);

        //查询数据
        List<Product> dataList = queryAll();

        //封装分页返回对象
        PageInfo<Product> pageList = new PageInfo<>(dataList);

        return pageList;
    }

    @Override
    public List<Product> queryAll() {
        Example example = new Example(Product.class);
        example.setOrderByClause("product_code asc");

        return productMapper.selectByExample(example);
    }


    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateProduct(Product product) throws Exception {
        Integer originalStatus = this.getProductByCode(product.getProductCode()).getProductState(); //阴极板更新前的状态

        /**
         * 更新阴极板
         */
        productMapper.updateProduct(product);

        /**
         * 插入阴极板时间线日志(阴极板状态更新日志)
         */
        if(originalStatus != product.getProductState()){
            operLogService.insert(product.getProductCode(),
                    3,
                    product.getProductState(),
                    "状态变更为:"+dataInfoService.getDataInfoDetailByParentCodeAndDataCode("PRODUCT_STATUS",product.getProductState().toString()).getDataName(),
                    product.getUserid());
        }

        /**
         * 阴极板完成维修后的工作
         */
        if(originalStatus == 1 && product.getProductState() != 1){
            //阴极板的维修信息置空
            product.setMaintainType(null); //维修类型
            product.setUpdateMaintainDate(null); //维修时间
        }

        /**
         * 生成阴极板维修历史记录
         * 插入阴极板时间线日志(维修日志)
         */
        if(product.getProductState() == 1){
            /**
             * 生成阴极板维修历史记录
             */
            MaintainHistory maintainHistory = new MaintainHistory();
            maintainHistory.setMaintainType(product.getMaintainType());
            maintainHistory.setProductId(product.getId());
            maintainHistory.setProductCode(product.getProductCode());
            maintainHistory.setMaintainTime(product.getUpdateMaintainDate());
            maintainHistory.setMaintainerId(product.getUserid());
            maintainHistory.setMaintainerName(userService.getUserById(product.getUserid()).getRealname());

            maintainHistoryService.addMaintainHistory(maintainHistory);

            /**
             * 插入阴极板时间线日志(维修日志)
             */
            operLogService.insert(product.getProductCode(),
                    1,
                    product.getProductState(),
                    "当前阴极板为:维修状态，维修类型为:"+dataInfoService.getDataInfoDetailByParentCodeAndDataCode("MAINTAIN_TYPE",product.getMaintainType().toString()).getDataName(),
                    product.getUserid());
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ProductVo getInfo(String scanCode, String userId, boolean flag) {
        /**
         * 根据阴极板编码获取阴极板信息
         */
        ProductVo product = productMapper.selectByCode(scanCode);

        //初始化搜索历史记录
        SearchHistory searchHistory = new SearchHistory();

        if(product != null){
            /**
             * 初始化阴极板的动态检测记录数据
             */
//            Example example2 = new Example(IndustryData.class);
//            Example.Criteria criteria2 = example2.createCriteria();
//            criteria2.andEqualTo("plateno",scanCode);
//            List<IndustryData> industryDataList = industryDataMapper.selectByExample(example2);
//            product.setIndustryDataList(industryDataList);

            //设置本次搜索历史的垂直度值
            searchHistory.setVerticality(product.getProductValue());

            //查询阴极板是否被收藏
            Example example3 = new Example(CollectHistory.class);
            Example.Criteria criteria3 = example3.createCriteria();
            criteria3.andEqualTo("userId",userId);
            criteria3.andEqualTo("collectCode",scanCode);
            List<CollectHistory> collectHistoryList = collectHistoryMapper.selectByExample(example3);
            if(collectHistoryList != null && collectHistoryList.size() > 0)
                product.setCollectStatus(1);
            else
                product.setCollectStatus(2);

            //阴极板的导电棒尺寸格式化显示
            if(product.getDdbLength() != null && product.getDdbWidth() != null && product.getDdbHeight() != null)
                product.setDdbSize(product.getDdbLength() + "*" + product.getDdbWidth() + "*" + product.getDdbHeight());
            else
                product.setDdbSize("");

            //阴极板尺寸格式化显示
            if(product.getYjbLength() != null && product.getYjbWidth() != null && product.getYjbHeight() != null)
                product.setYjbSize(product.getYjbLength() + "*" + product.getYjbWidth() + "*" + product.getYjbHeight());
            else
                product.setYjbSize("");
        }

        //添加搜索记录
        searchHistory.setSearchCode(scanCode);
        searchHistory.setUserId(userId);
        searchHistory.setSearchDate(new Date());

        //根据标识决定是否插入搜索历史
        if(flag)
            searchHistoryMapper.insertSelective(searchHistory);

        return product;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateState(ProductVo productVo) throws Exception {
        /**
         * 根据阴极板编码获取对应记录
         */
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productCode",productVo.getProductCode());
        Product product = productMapper.selectOneByExample(example);

        /**
         * 更新阴极板状态
         */
        if(product != null){
            if(productVo.getProductState() != null) {
                product.setProductState(productVo.getProductState());
                product.setUpdateStateDate(new Date());
                product.setUserid(productVo.getUserid());

                if(productVo.getProductState() == 1){
                    product.setMaintainType(productVo.getMaintainType());
                    product.setUpdateMaintainDate(new Date());
                }else{
                    product.setMaintainType(null);
                    product.setUpdateMaintainDate(null);
                }
            }

            this.updateProduct(product);
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void addProduct(Product product) {
        product.setCreatetime(new Date());
        product.setUpdateStateDate(new Date());
        product.setProductState(2);//设置为备用

        productMapper.insertSelective(product);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void deleteProduct(Integer id) {
        productMapper.deleteByPrimaryKey(id);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public int checkCount(String startProductCode, String endProductCode) {

        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andBetween("productCode", startProductCode, endProductCode);
        List<Product> productList = productMapper.selectByExample(example);

        return productList==null?0:productList.size();
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<VerticalityData> getList() {
        List<VerticalityData> list = verticalityDataMapper.selectAll();
        return list;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void copyData(List<Product> productList) {
        productMapper.insertList(productList);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Product> getAbsentList(String startProductCode, String endProductCode) {
        List<Product> absentList = new ArrayList<>();//缺失的阴极板列表
        int length = startProductCode.length();

        List<Product> existList = productMapper.getExistList(startProductCode,endProductCode);
        Long startCode = Long.valueOf(startProductCode);
        Long endCode = Long.valueOf(endProductCode);
        if(existList == null || existList.size() == 0){
            for(long i = startCode;i<=endCode;i++){
                addProduct(absentList,i,length);
            }
        }else{
            out:for(long i = startCode;i<=endCode;i++){
                if(existList.size() == 0){
                    addProduct(absentList,i,length);
                }else{
                    for(int j=0;j<existList.size();j++){
                        if(i == Long.valueOf(existList.get(j).getProductCode())){
                            existList.remove(j);
                            continue out;
                        }
                    }
                    addProduct(absentList,i,length);
                }
            }
        }


        return absentList;
    }

    private void addProduct(List<Product> list,long code,int length){
        Product addProduct = new Product();
        int len = 0;
        long temp = code;
        while(temp/10 > 0){
            len++;
            temp = temp/10;
        }
        if(temp>0)
            len++;
        if(len == length)
            addProduct.setProductCode(String.valueOf(code));
        else{
            String resultCode = String.valueOf(code);
            for(int i=0;i<length-len;i++){
                resultCode = "0" + resultCode;
            }
            addProduct.setProductCode(resultCode);
        }
        addProduct.setCreatetime(new Date());
        addProduct.setUpdateStateDate(new Date());
        list.add(addProduct);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void addProductList(List<Product> productList) {
        //阴极板初始化
        for (Product product:productList){
            product.setCreatetime(new Date());
            product.setUpdateStateDate(new Date());
        }

        productMapper.insertList(productList);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateProductState(String projectCode) {
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLike("productCode",projectCode + "%");
        List<Product> productList = productMapper.selectByExample(example);

        if(productList == null || productList.size() == 0)
            return;
        else{
            for (Product product : productList) {
                String pCode = product.getProductCode();
                Calendar calendar = new GregorianCalendar();
                calendar.add(Calendar.DAY_OF_MONTH,-7);
                Date time = calendar.getTime();

                Example example2 = new Example(IndustryData.class);
                Example.Criteria criteria2 = example2.createCriteria();
                criteria2.andEqualTo("plateno",pCode);
                criteria2.andGreaterThanOrEqualTo("datatime",time);
                int count = industryDataMapper.selectCountByExample(example2);

                if(count>0){
                    product.setProductState(MaintainType.Using.getCode());
                }else if(product.getProductState()==MaintainType.Using.getCode()){
                    product.setProductState(MaintainType.Reserve.getCode());
                }
                //product.setUpdateStateDate(new Date());
                productMapper.updateProduct(product);
            }
        }
    }

    @Override
    public ProductCountVo getProductCount(String productCode, Integer productState, Integer maintainType,
                                          String factoryId, String subFactoryId, String userid) {
        ProductCountVo count = productMapper.getProductCount(productCode,productState,maintainType,factoryId,subFactoryId,userid);
        /**
         * 设置总板数
         * 总板数=在线板数+备用板数+维修板数+报废板数
         */
        count.setSum(count.getOnline()+count.getOffline()+count.getMaintain());

        return productMapper.getProductCount(productCode,productState,maintainType,factoryId,subFactoryId,userid);
    }

    //    @Transactional(propagation = Propagation.SUPPORTS)
//    @Override
//    public ProductVo getProductCount(ProductVo queryVo) {
//
//        ProductVo productVo = productMapper.getProductCount(queryVo);
//
//        return productVo;
//    }
//
//    @Transactional(propagation = Propagation.SUPPORTS)
//    @Override
//    public List<ProductVo> getAllProductCounts(String userId) {
//
//        List<Factory> factoryList = factoryMapper.getFactory(userId);
//
//        List<ProductVo> productVoList = new ArrayList<>();
//        for (Factory factory : factoryList) {
//            ProductVo productVo = new ProductVo();
//            productVo.setFactoryId(factory.getId());
//
//            productVo = productMapper.getProductCount(productVo);
//
//            productVo.setFactoryId(factory.getId());
//            productVo.setFactoryName(factory.getFactoryName());
//
//            productVoList.add(productVo);
//        }
//
//        return productVoList;
//    }

    @Override
    public ProductCountVo getProductCountBySubFactoryId(String subFactoryId) {
        //获取目标车间下的阴极板统计信息
        ProductCountVo count = getProductCount(null,null,null,null,subFactoryId,null);
        //设置车间名和车间id
        count.setFactoryId(subFactoryId);
        count.setFactoryName(factoryService.findById(subFactoryId).getFactoryName());

        //设置未编码阴极板的数量
        count.setUncode(getUncodeNumBySubFactoryId(subFactoryId));
        /**
         * 设置总板数
         * 总板数=在线板数+备用板数+维修板数+报废板数
         */
        count.setSum(count.getOnline()+count.getOffline()+count.getMaintain());
        return count;
    }

    @Override
    public ProductCountVo getProductCountByFactoryId(String factoryId,String userId) {
        if(userService.iSAdminByUserId(userId)){
            userId = null;
        }
        //获取目标车间下的阴极板统计信息
        ProductCountVo count = getProductCount(null,null,null,factoryId,null,userId);

        //设置工厂名和工厂id
        count.setFactoryId(factoryId);
        count.setFactoryName(factoryService.findById(factoryId).getFactoryName());

        //设置未编码阴极板的数量
        count.setUncode(getUncodeNumByFactoryId(factoryId));

        /**
         * 设置总板数
         * 总板数=在线板数+备用板数+维修板数+报废板数
         */
        count.setSum(count.getOnline()+count.getOffline()+count.getMaintain());
        return count;
    }

    @Override
    public List<ProductCountVo> getProductCountByUserId(String userId) {
        //获取用户拥有访问权限的所有工厂
        List<Factory> factories = factoryService.getFactory(userId);

        //遍历工厂分别获取对应的阴极板统计信息
        List<ProductCountVo> productCounts = new ArrayList<>();
        for (Factory factory:factories){
            productCounts.add(getProductCountByFactoryId(factory.getId(),userId));
        }

        return productCounts;
    }

//    /**
//     * 获取客户端阴极板管理表格数据
//     * @param userId
//     */
//    @Override
//    public ProductVo getClientProductCounts(String userId) {
//        //根据需求描述，一个客户只有可能被分配一个车间
//        String subFactoryId = userService.getUserById(userId).getSubFactoryId();
//
//        //获得在线，维修，备用板的数目
//        ProductVo productVo = new ProductVo();
//        productVo.setSubFactoryId(subFactoryId);
//        productVo = productMapper.getProductCount(productVo);
//        productVo.setSum(productVo.getOnline() + productVo.getOffline() + productVo.getMaintain());
//
//        //获得无编号板数
//        Integer uncodeNum = productMapper.getUncodeNumBySubFactoryId(subFactoryId);
//        productVo.setUncodeNum(uncodeNum);
//        //获取今年的报废板数和新增板数
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.DAY_OF_YEAR, 1);
//        Date firstDayOfYear = calendar.getTime();
//        Date now = new Date();
//        productVo.setScrap(productMapper.getScrapNum(subFactoryId, firstDayOfYear, now));
//        productVo.setNewAdd(productMapper.getNewAddNum(subFactoryId, firstDayOfYear, now));
//
//        productVo.setCycle(factoryMapper.getCycle(subFactoryId));
//
//        //设置车间名称
//        productVo.setSubFactoryName(factoryMapper.selectByPrimaryKey(subFactoryId).getFactoryName());
//        return productVo;
//    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ProductNumVo> getFactoryAndProductCount() {
        return productMapper.getFactoryAndProductCount();
    }

    @Override
    public Integer getUncodeNumBySubFactoryId(String subFactoryId) {
        return productMapper.getUncodeNumBySubFactoryId(subFactoryId);
    }

    @Override
    public Integer getUncodeNumByFactoryId(String factoryId) {
        int count = 0;
        List<Factory> subFactories = factoryService.getSubFactoryById(factoryId);
        for (Factory subFactory:subFactories){
            count+=getUncodeNumBySubFactoryId(subFactory.getId());//无编码阴极板数累加
        }
        return count;
    }

    @Override
    public List<Product> selectUpdateProduct(){
        return  productMapper.selectUpdateProduct();
    }

    @Override
    public List<MaintainDataVo> selectProductMaintainData(Integer maintainType, String productCode) {
        return this.selectProductMaintainData(maintainType,productCode,null,null,null);
    }

    @Override
    public List<MaintainDataVo> selectProductMaintainData(Integer maintainType, String productCode, String factoryId,
                                                          String subFactoryId, String userId) {
        if(!StringUtils.isEmpty(userId)){
            return productMapper.selectProductMaintainData(maintainType,productCode,null,null,userId);
        }else if (!StringUtils.isEmpty(subFactoryId)){
            return productMapper.selectProductMaintainData(maintainType,productCode,null,subFactoryId,null);
        }else if(!StringUtils.isEmpty(factoryId)){
            return productMapper.selectProductMaintainData(maintainType,productCode,factoryId,null,null);
        }
        return productMapper.selectProductMaintainData(maintainType,productCode,null,null,null);
    }

    @Override
    public List<MaintainDataVo> selectProductMaintainDataByFactoryId(Integer maintainType, String productCode,
                                                                     String factoryId) {
        return this.selectProductMaintainData(maintainType,productCode,factoryId,null,null);
    }

    @Override
    public List<MaintainDataVo> selectProductMaintainDataByUserId(Integer maintainType, String productCode,
                                                                        String userId) {
        return this.selectProductMaintainData(maintainType,productCode,null,null,userId);
    }

    @Override
    public List<MaintainDataVo> selectProductMaintainDataBySubFactoryId(Integer maintainType, String productCode,
                                                                  String subFactoryId) {
        return this.selectProductMaintainData(maintainType,productCode,null,subFactoryId,null);
    }

    @Override
    public Product getProductByCode(String productCode) {
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productCode",productCode);
        Product product = productMapper.selectOneByExample(example);

        return product;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public void insertSearchHistory(String productCode,String userId) {
        ProductVo productInfo = this.getProductInfoByCode(productCode);

        if(productInfo != null){
            SearchHistory searchHistory = new SearchHistory();
            searchHistory.setSearchCode(productCode);
            searchHistory.setVerticality(productInfo.getProductValue());
            searchHistory.setUserId(userId);
            searchHistory.setSearchDate(new Date());
            searchHistoryMapper.insertSelective(searchHistory);
        }

    }

}
